package abg.core.common.ws.handler;

import abg.core.common.security.AuthUser;
import abg.core.common.security.AuthKit;
import abg.core.domain.sys.SRS;
import com.alibaba.fastjson2.JSONObject;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 处理文本信息
 */
@Slf4j
@Component
@EnableScheduling
@ChannelHandler.Sharable
public class TextHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    //用于记录和管理所有客户端的channle
    public static ConcurrentHashMap<String, Channel> channelPhoneAll = new ConcurrentHashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
        String text = frame.text();
        log.info("接收到消息 text==> {}", text);

        JSONObject param = JSONObject.parseObject(text);
        AuthUser currentUser = AuthKit.getCurrentUser(param.getString("token"));
        String type = param.getString("type");
        String client = param.getString("client");

        //注册手机端用户
        if ("REGISTER_MT".equals(type) && client.equals("PHONE") && currentUser != null) {
            channelPhoneAll.put(client + currentUser.getUserId(), ctx.channel());
            log.info("注册成功---> {} {}", JSONObject.toJSONString(param), JSONObject.toJSONString(currentUser));
            SRS<Object> srs = SRS.bySuccess("注册成功");
            srs.set("type", "REGISTER_SUCCESS");
            ctx.channel().writeAndFlush(new TextWebSocketFrame(srs.toJSONString()));
        } else {
            log.info("身份认证失败==> {} {}", ctx.channel().id().asLongText(), text);
            ctx.channel().close();
        }
    }

    /**
     * 连接成功回调
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info("连接成功--->" + ctx.channel().id().asLongText());
    }

    /**
     * 连接被移除后 回调
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        log.info("连接被移除--->" + ctx.channel().id().asLongText());
    }

    /**
     * 连接异常回调
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.info("发生异常之后关闭连接（关闭channel），随后从ChannelGroup中移除--->" + ctx.name());
        cause.printStackTrace();
        ctx.channel().close();
    }

    //每1分钟,清理断开的连接，释放内存
    //@Scheduled(cron = "0/10 * * * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void clearCloseChannel() {
        Enumeration<String> keys = TextHandler.channelPhoneAll.keys();
        Iterator<String> iterator = keys.asIterator();
        while (iterator.hasNext()) {
            String channelKey = iterator.next();
            Channel channel = TextHandler.channelPhoneAll.get(channelKey);
            if (!channel.isOpen()) {
                TextHandler.channelPhoneAll.remove(channelKey);
            }
        }
    }
}
